package com.pai4j.common.util;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Base64;

/**
 * Aes  工具类
 *
 * @author: CYM-pai
 * @date: 2025/05/04 20:44
 **/
@Slf4j
public class AESUtil {

    /***
     * AES 加密
     */
    private static final String KEY_ALGORITHM = "AES";

    /***
     * 密钥长度16
     */
    private static final int KEY_LEN = 16;

    /****
     * 填充方式 AES/CBC/PKCS5Padding
     */
    public static final String AES_CBC_PKCS5_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /***
     * 加密
     * @param key 密钥
     * @param content 原文
     * @return
     * @throws GeneralSecurityException
     */
    public static String encrypt(String key, String content) {
        try {
            byte[] keyBytes = getKeyBytes(key);
            byte[] buf = new byte[KEY_LEN];
            System.arraycopy(keyBytes, 0, buf, 0, Math.max(keyBytes.length, buf.length));
            Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(buf, KEY_ALGORITHM), new IvParameterSpec(keyBytes));
            byte[] doFinal = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            return new String(Base64.getEncoder().encode(doFinal));
        } catch (Exception e) {
            log.error("AES.encrypt error. content:{}", content, e);
        }
        return null;
    }

    /***
     * 解密
     * @param key 密钥
     * @param encryptStr 密文
     * @return
     * @throws GeneralSecurityException
     */
    public static String decrypt(String key, String encryptStr) {
        try {
            byte[] crypted = Base64.getDecoder().decode(encryptStr);
            byte[] keyBytes = getKeyBytes(key);
            byte[] buf = new byte[KEY_LEN];
            System.arraycopy(keyBytes, 0, buf, 0, Math.max(keyBytes.length, buf.length));
            Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(buf, KEY_ALGORITHM), new IvParameterSpec(keyBytes));
            byte[] doFinal = cipher.doFinal(crypted);
            return new String(doFinal);
        } catch (Exception e) {
            log.error("AES.encrypt error. encryptStr:{}", encryptStr, e);
        }
        return null;
    }

    private static byte[] getKeyBytes(String key) {
        byte[] bytes = key.getBytes();
        return bytes.length == KEY_LEN ? bytes : Arrays.copyOf(bytes, KEY_LEN);
    }
}